package com.mingqijia.gassafety.webserver.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.ResetlogMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.constant.PageColumnConst;
import com.mingqijia.gassafety.shared.constant.TemplateTypeEnum;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.HeaderUtil;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageColumns;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.LatestLogListRequest;
import com.mingqijia.gassafety.webserver.request.RecordLogRequest;
import com.mingqijia.gassafety.webserver.response.CompanyResponse;
import com.mingqijia.gassafety.webserver.response.ResetLogResponse;
import com.mingqijia.gassafety.webserver.response.sk.AlarmSupplierListVo;
import com.mingqijia.gassafety.webserver.response.sk.ConsoleSkSupplierListResponse;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.cmp.EquipmentCmpService;
import com.mingqijia.gassafety.webserver.service.workorder.DtuBindingOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.ORG_MAP_SUBSCODE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wanghai
 * @since 2022-03-10
 */
@Service
@Slf4j
public class ResetlogServiceImpl extends ServiceImpl<ResetlogMapper, Resetlog> implements ResetlogService {

    @Autowired
    ResetlogMapper resetlogMapper;
    @Autowired
    EquipmentService equipmentService;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    DtuBindingOrderService dtuBindingOrderService;
    @Autowired
    HeaderUtil headerUtil;
    @Autowired
    CompanyService companyService;
    @Autowired
    UserPermissionService userPermissionService;

    @Autowired
    EquipmentCmpService equipmentCmpService;

    @Override
    public PageUtil<ResetLogResponse> resetList(RecordLogRequest req) {
        List<ResetLogResponse> resultList = new ArrayList<>();
        List<Dtu> equipmentList = new ArrayList<>();
        req.setTemplateType(headerUtil.getTemplateType());
        //页面字段模板
        List<PageColumns> pageColumns = new ArrayList<>();
        if(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode() == req.getTemplateType()){
            pageColumns = PageColumnConst.add(PageColumnConst.ResetGasUserTitles, PageColumnConst.ResetGasUserIndices);
        }else if(TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == req.getTemplateType()){
            pageColumns = PageColumnConst.add(PageColumnConst.ResetVccUserTitles, PageColumnConst.ResetVccUserIndices);
        }
        String spId = ApplicationUtils.getWorkingSpId();
        //1、根据spId换path
        String path = departmentService.getPath(spId);

        //2.1、设置查询条件
        if (!StringUtils.isEmpty(req.getImei()) || !StringUtils.isEmpty(req.getEquipmentName()) ||
                !StringUtils.isEmpty(req.getEquipmentManufacturer()) || !StringUtils.isEmpty(req.getEquipmentModel()) ||
                !StringUtils.isEmpty(req.getSubsCode()) || !StringUtils.isEmpty(req.getEquipmentType()) ||
                !StringUtils.isEmpty(req.getCustName()) || !StringUtils.isEmpty(req.getCustAddress()) ||
                !StringUtils.isEmpty(req.getCustPhone()) || !StringUtils.isEmpty(req.getIndustryType()) ||
                !StringUtils.isEmpty(req.getInstallationAddress()) || !StringUtils.isEmpty(req.getMemberId()) ||
                !StringUtils.isEmpty(req.getContactName()) || !StringUtils.isEmpty(req.getContactPhone()) || !StringUtils.isEmpty(req.getOrgCode()) ||
                !StringUtils.isEmpty(req.getCustomerAddress())) {
            LatestLogListRequest request = new LatestLogListRequest();
            //用的时候需参数类型和参数名一致
            BeanUtils.copyProperties(req, request);

            if (req.getEquipmentType() == null || StringUtils.isEmpty(req.getEquipmentType())) {
                request.setEquipmentTypes(new String[]{EquipmentType.INDEPENDENT_GAS_DETECTOR.getCode(),
                        EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode(), EquipmentType.HOME_GAS_DETECTOR.getCode()});
            }else{
                request.setEquipmentTypes(new String[]{req.getEquipmentType()});
            }

            //2.2 筛选出符合条件的dtu
            request.setSpId(spId);
            if(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode() == req.getTemplateType()){
                equipmentList = equipmentService.listEquipmentWithType1(request);
            }else if(TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == req.getTemplateType()){
                equipmentList = equipmentService.listEquipmentWithType2(request);
            }
            if (equipmentList.isEmpty()) {
                return new PageUtil(req.getPage(), req.getPageSize(), 0, resultList, pageColumns);
            }
        }
        //2.3 收集设备表的设备号
        List<Map<String,String>> imeiList = equipmentList.stream().map(a->{
            Map<String,String> map = new HashMap();
            if (a.getEquipmentType().equals(EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode())){
                map.put("imei",a.getIMEI().substring(0,a.getIMEI().length()-4));
                map.put("sub",a.getIMEI().substring(a.getIMEI().length()-3));
                return map;
            }else{
                map.put("imei",a.getIMEI());
                map.put("sub","1-1");
                return map;
            }
        }).collect(Collectors.toList());

        //3.1 根据条件查询复位记录表
        LambdaQueryWrapper<Resetlog> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Resetlog::getPath,path).orderByDesc(Resetlog::getTime);
        if (!imeiList.isEmpty()) {
            queryWrapper.and(lqw -> {
                for (Map<String, String> stringStringMap : imeiList) {
                    lqw.or(wrapper -> {
                        wrapper.eq(Resetlog::getDtuId,stringStringMap.get("imei"))
                                .eq(Resetlog::getSubIdentifier,stringStringMap.get("sub"));
                    });
                }
            });
        }
        if (!StringUtils.isEmpty(req.getTimeStart())) {
            queryWrapper.ge(Resetlog::getTime,req.getTimeStart());
        }
        if (!StringUtils.isEmpty(req.getTimeEnd())) {
            queryWrapper.le(Resetlog::getTime,req.getTimeEnd());
        }
        //数据权限
        List<Integer> permissionConsumerIds = userPermissionService.getDepartConsumerIds(spId, ApplicationUtils.getUserId());
        if( null!=permissionConsumerIds && !permissionConsumerIds.isEmpty()){
            queryWrapper.in(Resetlog::getConsumerId,permissionConsumerIds);
        }

        Page pageHelper = PageHelper.startPage(req.getPage(), req.getPageSize());
        List<Resetlog> resetlogList = resetlogMapper.selectList(queryWrapper);
        //3.2 收集复位记录表的设备号
        List<String> imeis = new ArrayList();
        for (Resetlog resetlog : resetlogList) {
            imeis.add(resetlog.getDtuId());
            imeis.add(resetlog.getDtuId()+"-"+resetlog.getSubIdentifier());
        }
        //4 查询设备信息
        if (!imeis.isEmpty()) {
            LambdaQueryWrapper<Dtu> dtuLambdaQueryWrapper = new LambdaQueryWrapper<>();
            if (req.getEquipmentType() == null || StringUtils.isEmpty(req.getEquipmentType())) {
                dtuLambdaQueryWrapper.in(Dtu::getEquipmentType, new String[]{EquipmentType.INDEPENDENT_GAS_DETECTOR.getCode(),
                        EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode(), EquipmentType.HOME_GAS_DETECTOR.getCode()});
            }else{
                dtuLambdaQueryWrapper.eq(Dtu::getEquipmentType, req.getEquipmentType());
            }
            dtuLambdaQueryWrapper.in(Dtu::getIMEI, imeis).eq(Dtu::getSpId, spId);
            List<Dtu> dtuList = equipmentService.list(dtuLambdaQueryWrapper);
            if (dtuList.isEmpty()) {
                return new PageUtil(req.getPage(), req.getPageSize(), 0, resultList, pageColumns);
            }

            //设备厂商名称
            ConsoleSkSupplierListResponse response = equipmentCmpService.supplierListRequest();
            log.info("调用厨房查询厂商接口返回：{}", response);
            List<AlarmSupplierListVo> supplierListVos = new ArrayList<>();
            if (response != null && response.getCode() == 0 && response.getData() != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(response.getData())) {
                supplierListVos = response.getData();
            }
            //4.2设置返回结果的设备信息
            Map<String, Dtu> dtuMap = dtuList.stream().collect(Collectors.toMap(Dtu::getIMEI, Dtu -> Dtu, (a1,a2) -> a1));
            List<DictionaryItemRespDTO> equipmentTypeList = holder.getDictionaryByKey(EquipmentType.DICT_CODE);
            for (Resetlog resetlog : resetlogList) {
                ResetLogResponse res = new ResetLogResponse();
                BeanUtils.copyProperties(resetlog, res);
                res.setImei(resetlog.getDtuId());
                if (dtuMap.containsKey(resetlog.getDtuId())) {
                    Dtu dtu = dtuMap.get(resetlog.getDtuId());
                    BeanUtils.copyProperties(dtu, res);
                    DictionaryItemRespDTO dict = getDict(equipmentTypeList, res.getEquipmentType());
                    res.setConsumerId(resetlog.getConsumerId());
                    res.setEquipmentTypeName(dict.getName());
                    res.setEquipmentName(dtu.getName());
                    res.setLatestTime(resetlog.getTime());
                    //设备厂商名称
                    List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                            res.getEquipmentManufacturer())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(listVos)) {
                        res.setManufactureName(listVos.get(0).getMsName());
                    }

                    if (TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == req.getTemplateType()) {
                        res.setInstallationAddress(dtu.getInstallationAddress());
                    }
                } else if (dtuMap.containsKey(resetlog.getDtuId() + "-" + resetlog.getSubIdentifier())) {
                    Dtu dtu = dtuMap.get(resetlog.getDtuId() + "-" + resetlog.getSubIdentifier());
                    BeanUtils.copyProperties(dtu, res);
                    DictionaryItemRespDTO equipmentTypeNameDict = getDict(equipmentTypeList, res.getEquipmentType());
                    res.setConsumerId(resetlog.getConsumerId());
                    res.setEquipmentTypeName(equipmentTypeNameDict.getName());
                    res.setEquipmentName(dtu.getName());
                    res.setLatestTime(resetlog.getTime());
                    res.setImei(dtu.getIMEI());
                    //设备厂商名称
                    List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                            res.getEquipmentManufacturer())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(listVos)) {
                        res.setManufactureName(listVos.get(0).getMsName());
                    }
                    if (TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == req.getTemplateType()) {
                        res.setInstallationAddress(dtu.getInstallationAddress());
                    }
                }
                res.setId(resetlog.getId().longValue());
                resultList.add(res);

            }
            //5 客户信息
            List<Integer> consumerIds = dtuList.stream().map(Dtu::getConsumerId).collect(Collectors.toList());
            LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
            consumerQueryWrapper.eq(Consumer::getSpId, spId).in(Consumer::getId, consumerIds);
            List<Consumer> consumerList = consumerService.list(consumerQueryWrapper);
            Map<Integer, Consumer> consumerMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(consumerList)) {
                consumerMap = consumerList.stream().collect(Collectors.toMap(Consumer::getId, Consumer -> Consumer, (a1, a2) -> a1));
            }

            List<String> spIds = new ArrayList<>();
            spIds.add(spId);
            //查询组织架构名称
            List<CompanyResponse> companyNameList = companyService.queryCompanyNameList(spIds);
            Map<String, String> companyNameMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(companyNameList)) {
                companyNameMap = companyNameList.stream().collect(Collectors.toMap(CompanyResponse::getSpId, CompanyResponse::getName));
            }
            //批量查询字典
            List<DictionaryItemRespDTO> orgMapSubsCodeList = holder.getDictionaryByKey(ORG_MAP_SUBSCODE);
            Map<String, String> orgSubsCodeMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(orgMapSubsCodeList)) {
                orgSubsCodeMap = orgMapSubsCodeList.stream().collect(Collectors.toMap(DictionaryItemRespDTO::getDescription, DictionaryItemRespDTO::getCompanyName));
            }
            for (ResetLogResponse resetLogResponse : resultList) {
                if (consumerMap.containsKey(resetLogResponse.getConsumerId())) {
                    Consumer consumer = consumerMap.get(resetLogResponse.getConsumerId());
                    resetLogResponse.setCustomerAddress(consumer.getCustomerAddress());
                    //紫荆设备
                    if (resetLogResponse.getEquipmentFrom() == Constants.ZJ_EQUIPMENT_FROM){
                        resetLogResponse.setMemberId(consumer.getMemberId());
                        resetLogResponse.setCustPhone(consumer.getCustPhone());
                    }
                    if (org.apache.commons.lang3.StringUtils.isNotEmpty(consumer.getOrgCode()) && orgSubsCodeMap.containsKey(consumer.getOrgCode())) {
                        resetLogResponse.setCompanyName(orgSubsCodeMap.get(consumer.getOrgCode()));
                    } else {
                        if (companyNameMap.containsKey(consumer.getSpId())) {
                            resetLogResponse.setCompanyName(companyNameMap.get(consumer.getSpId()));
                        }
                    }
                }
            }
            if(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode() == req.getTemplateType()){
                List<DictionaryItemRespDTO> industryTypeCodeList = holder.getDictionaryByKey(Constants.INDUSTRY_TYPE_CODE);
                //燃气用户
                for (ResetLogResponse resetLogResponse : resultList) {
                    if (consumerMap.containsKey(resetLogResponse.getConsumerId())) {
                        Consumer consumer = consumerMap.get(resetLogResponse.getConsumerId());
                        resetLogResponse.setSubsCode(consumer.getSubsCode());
                        resetLogResponse.setIndustryType(consumer.getIndustryType());
                        resetLogResponse.setCustName(consumer.getCustName());
                        resetLogResponse.setCustAddress(consumer.getCustAddress());
                        resetLogResponse.setCustPhone(consumer.getCustPhone());
                        resetLogResponse.setCustomerAddress(consumer.getCustomerAddress());
                        //设置行业类型名称
                        if (!StringUtils.isEmpty(resetLogResponse.getIndustryType())) {
                            DictionaryItemRespDTO communicationModeDict = getDict(industryTypeCodeList, resetLogResponse.getIndustryType());
                            resetLogResponse.setIndustryTypeName(communicationModeDict.getName());
                        }
                    }
                }
            }else if(TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == req.getTemplateType()) {
                //时刻助手用户
                LambdaQueryWrapper<DtuBindingOrder> lqw = new LambdaQueryWrapper<>();
                lqw.eq(DtuBindingOrder::getSpId, spId).in(DtuBindingOrder::getConsumerId, consumerIds);
                List<DtuBindingOrder> bindings = dtuBindingOrderService.list(lqw);
                Map<String, DtuBindingOrder> bindingOrderMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(bindings)) {
                    bindingOrderMap = bindings.stream().collect(Collectors.toMap(DtuBindingOrder::getDeviceId, DtuBindingOrder -> DtuBindingOrder, (a1, a2) -> a1));
                }
                List<DictionaryItemRespDTO> industryTypeCodeList = holder.getDictionaryByKey(Constants.INDUSTRY_TYPE_CODE);
                for (ResetLogResponse resetLogResponse : resultList) {
                    if (bindingOrderMap.containsKey(resetLogResponse.getImei())) {
                        DtuBindingOrder dtuBindingOrder = bindingOrderMap.get(resetLogResponse.getImei());
                        resetLogResponse.setMemberId(dtuBindingOrder.getMemberId());
                        resetLogResponse.setContactName(dtuBindingOrder.getCustName());
                        resetLogResponse.setContactPhone(dtuBindingOrder.getPhone());
                        Consumer consumerWithContacts = consumerList.stream().filter(item -> item.getId().equals(dtuBindingOrder.getConsumerId()))
                                .collect(Collectors.toList()).get(0);
                        resetLogResponse.setIndustryType(consumerWithContacts.getIndustryType());
                        //行业类型
                        if (!StringUtils.isEmpty(resetLogResponse.getIndustryType())) {
                            DictionaryItemRespDTO communicationModeDict = getDict(industryTypeCodeList, resetLogResponse.getIndustryType());
                            resetLogResponse.setIndustryTypeName(communicationModeDict.getName());
                        }
                    }
                }
            }
        }

        PageUtil pageInfo = new PageUtil(req.getPage(), req.getPageSize(), pageHelper.getTotal(), resultList, pageColumns);
        return pageInfo;
    }

    private DictionaryItemRespDTO getDict(List<DictionaryItemRespDTO> equipmentTypeList, String code) {
        return equipmentTypeList.stream().filter(a -> a.getValue().equals(
                code)).collect(Collectors.toList()).get(0);
    }

    @Override
    @DS("db2")
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void insert(Resetlog resetLog) {
        resetlogMapper.insert(resetLog);
    }
}
